<template>
  <div ref="boxRef" class="chart-box map-box">
    <div class="chart-header">
      <h3>
        <span class="title-icon">|</span>
        <span>商家分布（高德地图）</span>
      </h3>
      <button class="fullscreen-btn" @click="toggleFullscreen">⛶</button>
    </div>
    <div ref="amapRef" class="amap-container" style="width:100%;height:100%;min-height:400px;"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { subscribeToChart } from '@/services/dataHub';

const boxRef = ref<HTMLElement | null>(null);
const amapRef = ref<HTMLElement | null>(null);
let map: any = null;
let markers: any[] = [];
let unsubscribe: (() => void) | null = null;
const AMAP_KEY = 'baae1329482fa3430c0f2786616a2f67';

function loadAMapScript() {
  return new Promise<void>((resolve, reject) => {
    // @ts-ignore
    if (window.AMap) {
      resolve();
      return;
    }
    const script = document.createElement('script');
    script.src = `https://webapi.amap.com/maps?v=2.0&key=${AMAP_KEY}`;
    script.onload = () => resolve();
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

function clearMarkers() {
  if (markers.length && map) {
    markers.forEach(m => map.remove(m));
    markers = [];
  }
}

function renderMarkers(list: any[]) {
  clearMarkers();
  // @ts-ignore
  if (!map || !Array.isArray(list)) return;
  list.forEach(item => {
    if (!item.coord || item.coord.length !== 2) return;
    // 自定义彩色圆点+阴影
    // @ts-ignore
    const marker = new window.AMap.Marker({
      position: item.coord,
      title: item.name,
      anchor: 'center',
      content: `<div style='
        width:22px;height:22px;border-radius:50%;
        background:linear-gradient(135deg,#4a9eff,#5dd465 80%);
        box-shadow:0 0 12px #4a9eff99;
        display:flex;align-items:center;justify-content:center;'>
        <span style='color:#fff;font-size:13px;font-weight:600;'>●</span>
      </div>`
    });
    // 鼠标悬停弹窗
    marker.on('mouseover', () => {
      // @ts-ignore
      window.AMap.InfoWindow && new window.AMap.InfoWindow({
        content: `<div style='padding:8px 16px;font-size:15px;color:#333;'>${item.name}</div>`
      }).open(map, item.coord);
    });
    marker.on('mouseout', () => {
      // @ts-ignore
      map.clearInfoWindow && map.clearInfoWindow();
    });
    // @ts-ignore
    marker.setMap(map);
    markers.push(marker);
  });
}

function setupMapDataSubscription() {
  unsubscribe = subscribeToChart('map', (data: any) => {
    const list = Array.isArray(data) ? data : [];
    // 兼容原数据结构
    let points: any[] = [];
    list.forEach((group: any) => {
      if (Array.isArray(group?.children)) {
        group.children.forEach((item: any) => {
          if (item.value && item.value.length === 2) {
            points.push({
              name: item.name,
              coord: item.value,
            });
          }
        });
      }
    });
    renderMarkers(points);
  });
}

onMounted(async () => {
  await loadAMapScript();
  if (amapRef.value) {
    // @ts-ignore
    map = new window.AMap.Map(amapRef.value, {
      zoom: 4,
      center: [105, 36],
      mapStyle: 'amap://styles/dark',
      resizeEnable: true,
    });
  }
  setupMapDataSubscription();
});

onUnmounted(() => {
  if (unsubscribe) unsubscribe();
  clearMarkers();
  if (map) {
    map.destroy();
    map = null;
  }
});

function toggleFullscreen() {
  const box = boxRef.value;
  if (!box) return;
  const button = box.querySelector('.fullscreen-btn') as HTMLButtonElement | null;
  if (!box.classList.contains('fullscreen')) {
    box.classList.add('fullscreen');
    if (button) button.textContent = '✕';
    setTimeout(() => map?.resize(), 300);
    window.addEventListener('keydown', escListener);
  } else {
    box.classList.remove('fullscreen');
    if (button) button.textContent = '⛶';
    setTimeout(() => map?.resize(), 300);
    window.removeEventListener('keydown', escListener);
  }
}
function escListener(e: KeyboardEvent) {
  if (e.key === 'Escape') {
    const box = boxRef.value;
    if (box && box.classList.contains('fullscreen')) {
      toggleFullscreen();
    }
  }
}
</script>

<style scoped>
.amap-container {
  width: 100%;
  height: 100%;
  min-height: 400px;
}
</style>
